//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2003 Intrinsyc Europe Ltd.
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2004 Siemens AG
//
// Version: 1.1.2.5
// Date:    11. Jan. 2006
//////////////////////////////////////////////////////////////////////////////


#pragma once

//
// Forward declarations
//
class CRilHandle;
enum APIID;


//
// Globals
//
#define RSP_THREAD_SLEEP        100

#define COMMAND_QUEUE_SIZE      40
#define RESPONSE_QUEUE_SIZE     10

extern CPriorityQueue<CCommand, COMMAND_QUEUE_SIZE>* g_pCmdQ[];
extern CQueue<CResponse, RESPONSE_QUEUE_SIZE>* g_pRspQ[];

//
// Structures
//
struct REQUEUE_THREAD_DATA {
    CCommand* pCmd;
    DWORD dwDelay;
    COM_PORT_TYPE PortType;
};

struct QUEUE_THREAD_DATA {
    CRilHandle* pRilDevice;
    COM_PORT_TYPE PortType;
};

struct QUEUE_BLOCKING_DATA {
    CRITICAL_SECTION  csLock;
    PFN_CMD_PARSE     pfnParseOk;
    PFN_CMD_ERROR     pfnParseErr;
    LPVOID            pParam;
    HANDLE            hEvents[2];
};

extern QUEUE_BLOCKING_DATA g_QBlockingData[NUMBER_OF_PORTS];

// Routines
BOOL QueueCmd(COM_PORT_TYPE PortType, CRilInstanceHandle* const pHandle, const LPCSTR szCmd, const DWORD dwOptions, const APIID apiid,
              const PFN_CMD_PARSE pfnParse, CNotificationData* const pnd, HRESULT& rhrCmdID, const PFN_CMD_ERROR pfnError = NULL, const LPVOID pParseParam = NULL);
BOOL QueueCmdPriority(CRilInstanceHandle* const pHandle, const LPCSTR szCmd, const DWORD dwOptions, const APIID apiid,
              const PFN_CMD_PARSE pfnParse, CNotificationData* const pnd, HRESULT& rhrCmdID, const PFN_CMD_ERROR pfnError = NULL, const LPVOID pParseParam = NULL,
              const CME_TRANSLATION *pCMET = NULL, const PFN_PRE_CMD_CHECK pfnPreCheck = NULL, DWORD dwTimeout = 0);
BOOL QueueCmdWithRetry(COM_PORT_TYPE PortType, CRilInstanceHandle* const pHandle, const LPCSTR szCmd, const DWORD dwOptions, const APIID apiid,
              const PFN_CMD_PARSE pfnParse, CNotificationData* const pnd, HRESULT& rhrCmdID, DWORD dwRetries, DWORD dwRetryDelay, const PFN_CMD_ERROR pfnError = NULL, const LPVOID pParseParam = NULL);
BOOL QueueMultipartCmd(COM_PORT_TYPE PortType, CRilInstanceHandle* const pHandle, const LPCSTR szCmd, const LPCSTR szCmdPart2, const DWORD dwOptions, const APIID apiid,
              const PFN_CMD_PARSE pfnParse, CNotificationData* const pnd, HRESULT& rhrCmdID, const PFN_CMD_ERROR pfnError = NULL, const LPVOID pParseParam = NULL);
BOOL QueueMultipartCmdWithRetry(COM_PORT_TYPE PortType, CRilInstanceHandle* const pHandle, const LPCSTR szCmd, const LPCSTR szCmdPart2, const DWORD dwOptions, const APIID apiid,
              const PFN_CMD_PARSE pfnParse, CNotificationData* const pnd, HRESULT& rhrCmdID, const PFN_CMD_ERROR pfnError, const LPVOID pParseParam, DWORD dwRetries, DWORD dwRetryDelay);
BOOL QueueCmdWithTimeout(COM_PORT_TYPE PortType, CRilInstanceHandle* const pHandle, const LPCSTR szCmd, const LPCSTR szCmdPart2, const DWORD dwOptions, const APIID apiid,
              const PFN_CMD_PARSE pfnParse, CNotificationData* const pnd, HRESULT& rhrCmdID, DWORD dwTimeout, DWORD dwRetries, DWORD dwRetryDelay,
              const PFN_CMD_ERROR pfnError = NULL, const LPVOID pParseParam = NULL, const CME_TRANSLATION *pCMET = NULL, const PFN_PRE_CMD_CHECK pfnPreCheck = NULL);
BOOL RequeueCmdWithDelay(COM_PORT_TYPE PortType, CCommand* pCmd, DWORD dwDelay);
BOOL QueueCmdCMET(COM_PORT_TYPE PortType, CRilInstanceHandle* const pHandle, const LPCSTR szCmd, const DWORD dwOptions, const APIID apiid,
              const PFN_CMD_PARSE pfnParse, CNotificationData* const pnd, HRESULT& rhrCmdID, const CME_TRANSLATION *pCMET);
BOOL QueueInternalCmd(COM_PORT_TYPE PortType, CRilHandle* const pRilDevice, const LPCSTR szCmd, const DWORD dwOptions, const APIID apiid, DWORD dwTimeout, DWORD dwRetries, DWORD dwRetryDelay,
              const PFN_CMD_PARSE pfnParse = NULL, const PFN_CMD_ERROR pfnError = NULL, const LPVOID pParseParam = NULL, CNotificationData* const pnd = NULL);
BOOL QueueInternalCmdBlocking(COM_PORT_TYPE PortType, CRilHandle* const pRilDevice, const LPCSTR szCmd, const DWORD dwOptions, const APIID apiid, DWORD dwTimeout, DWORD dwRetries, DWORD dwRetryDelay,
              const PFN_CMD_PARSE pfnParse = NULL, const PFN_CMD_ERROR pfnError = NULL, const LPVOID pParseParam = NULL, CNotificationData* const pnd = NULL);
BOOL QueueCmdBlocking(COM_PORT_TYPE PortType, CRilInstanceHandle* const pHandle, const LPCSTR szCmd, const DWORD dwOptions, const APIID apiid, const PFN_CMD_PARSE pfnParse, CNotificationData* const pnd,
              HRESULT& rhrCmdID, DWORD dwTimeout, DWORD dwRetries, DWORD dwRetryDelay,    const PFN_CMD_ERROR pfnError = NULL, const LPVOID pParseParam = NULL);


// Thread procedures command COM port
DWORD WINAPI CmdThreadProc(LPVOID lpParameter);
DWORD WINAPI ReadThreadProc(LPVOID lpParameter);

